//
//  ScanController.m
//  kismet-frontend
//
//  Created by L. Preston Sego III on 7/17/09.
//  Copyright 2009 Precognition Inc.. All rights reserved.
//

#import "ScanController.h"

@implementation ScanController

-(id)init
{
    [_mainWindow setDocumentEdited:NO];
    
    //Init Prefs
    _prefsController = [[PrefsController alloc] init];
    
    //Init Plugins
    _pluginController = [[PluginController alloc] init];

    // connect to kismet
    _kismetController = [[KismetController alloc] init];
    [_kismetController connectAndSetupServer];
    
    _networkData = [[NetworkData alloc] init];
    
    return self;
}

-(void)awakeFromNib
{
    // Restore the Preferences
    //NSMutableDictionary *defaultValues = [NSMutableDictionary dictionary];
    static BOOL alreadyAwake = NO;
    
    // see if we've already been invoked
    if(!alreadyAwake)
        alreadyAwake = YES;
    else
        return;
    
    
    
    // update Info
    [_aboutVersion setTitleWithMnemonic:[[[NSBundle mainBundle] infoDictionary]
                            valueForKey:@"CFBundleVersion"]];
    [_mainWindow setTitle:[[[NSBundle mainBundle] infoDictionary]
              valueForKey:@"CFBundleExecutable"]];
    
    // load default view
    [_networksTableBay setContentView:_networksTableView];
    [self showNetworksView:nil];
    [_mainWindow center];
    
    //Restore Driver Info
    
}

#pragma mark toolbar commands

-(void)openFile:(id)sender
{
    
}

-(void)saveFile:(id)sender
{
    
}

-(void)newFile:(id)sender
{
    
}

-(void)showNetworksView:(id)sender
{
    [_mainWindow setContentView:_networksMaster];
    _currentTab = tabNetworks;
}

-(void)showNetworkDetails:(id)sender
{
    [_mainWindow setContentView:_detailsMaster];
    _currentTab = tabNetDetails;
}

-(void)showChannelDetails:(id)sender
{
    [_mainWindow setContentView:_channelDetailMaster];
    _currentTab = tabChanDetails;
}

-(void)showPluginManager:(id)sender
{
    [NSBundle loadNibNamed:@"Plugins" 
                     owner:_pluginController];
}

-(void)showServerComm:(id)sender
{
    [NSBundle loadNibNamed:@"DirectComm" 
                     owner:_kismetController];
}

-(void)crackNetwork:(id)sender
{
    
}

-(void)showPreferences:(id)sender
{
    [NSBundle loadNibNamed:@"Preferences" 
                     owner:_prefsController];
}

-(void)showHelp:(id)sender
{
    
}

-(void)scanToggle:(id)sender
{
/*    if(_scanning) {
		_scanning = NO;
		return [self stopScan];
	} else {
		_scanning = YES;
		return [self startScan];
	} */
}

-(void)changeSearchValue:(id)sender
{
    
}

#pragma mark -
#pragma mark Channel Detail View Methods
#pragma mark -
-(IBAction)switchOrientation:(id)sender
{
    if([_channelDetailMaster isVertical])
    {
        [_channelDetailMaster setVertical:NO];
    }
    else
    {
        [_channelDetailMaster setVertical:YES];
    }
    
    // update the change
    [_channelDetailMaster adjustSubviews];
    [_channelDetailMaster setNeedsDisplay:YES];

}

#pragma mark -
#pragma mark Table datasource methods
#pragma mark -

- (IBAction)updateNetworkTable:(id)sender complete:(bool)complete {
    int row;
    int i;
    
    if ([_networkData numberOfNetworks] != [_networksTable numberOfRows]) complete = YES;
        
    if (_currentTab == tabChanDetails) 
    {
        // update channel details
    } 
    else if (_currentTab == tabNetworks) 
    {
        if (_lastSorted) [_networkData sortWithShakerByColumn:_lastSorted order:_ascending];
        
        if (complete) 
        {
            [_networksTable reloadData];
            //if (_detailsPaneVisibile) [aInfoController reloadData];
            if ([_networkData netAtIndex:_selectedRow] != _currentNetwork)
            { //we lost our selected network
                for (i = [_networkData numberOfNetworks]; i>=0; i--)
                    if ([_networkData netAtIndex:i] == _currentNetwork) 
                    {
                        _selectedRow = i;
                        [_networksTable selectRow:i byExtendingSelection:NO];
                        break;
                    }
            }
        }
        else 
        {
            row = [_networkData nextChangedRow:0xFFFFFFFF];
            while (row != 0xFFFFFFFF) 
            {
                if ([_networkData netAtIndex:row] == _currentNetwork) 
                {
                    //if (_detailsPaneVisibile) [aInfoController reloadData];
                    _selectedRow = row;
                    [_networksTable selectRow:row byExtendingSelection:NO];
                }
                [_networksTable displayRect:[_networksTable rectOfRow:row]];
                row = [_networkData nextChangedRow:row];
            }
        }
    } 
    else if (_currentTab == tabNetDetails) 
    {
        if (complete) 
        {
            //[aInfoController reloadData];
            if ([_networkData netAtIndex:_selectedRow] != _currentNetwork)
            { //we lost our selected network
                for (i = [_networkData numberOfNetworks]; i>=0; i--)
                    if ([_networkData netAtIndex:i] == _currentNetwork)
                    {
                        _selectedRow = i;
                        [_networksTable selectRow:i byExtendingSelection:NO];
                        break;
                    }
            }
        } 
        else
        {
            row = [_networkData nextChangedRow:0xFFFFFFFF];
            while (row != 0xFFFFFFFF) {
                if ([_networkData netAtIndex:row] == _currentNetwork)
                {
                    //[aInfoController reloadData];
                    _selectedRow = row;
                    [_networksTable selectRow:row byExtendingSelection:NO];
                }
                row = [_networkData nextChangedRow:row];
            }
        }
    }
}

- (id) tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex {
    Network *net = [_networkData netAtIndex:rowIndex];
    
	return [[net cache] objectForKey:[aTableColumn identifier]];
}

- (int)numberOfRowsInTableView:(NSTableView *)aTableView {
    return [_networkData numberOfNetworks];
}

- (void)tableViewSelectionDidChange:(NSNotification *)aNotification {
     _currentNetwork = [_networkData netAtIndex:[_networksTable selectedRow]];
}

- (void)tableView:(NSTableView*)tableView didClickTableColumn:(NSTableColumn *)tableColumn {
    NSString *ident = [tableColumn identifier];
    
    if(![tableView isEqualTo:_networksTable]) return;
    
    if ((_lastSorted) && ([_lastSorted isEqualToString:ident])) {
        if (_ascending) _ascending=NO;
        else {
            [_lastSorted release];
            _lastSorted = Nil;
            [tableView setIndicatorImage:Nil 
                           inTableColumn:tableColumn];
            [tableView setHighlightedTableColumn:Nil];
            [tableView reloadData];
            return;
        }
    } else {
        _ascending=YES;
        if (_lastSorted) {
            [tableView setIndicatorImage:nil 
                           inTableColumn:[tableView tableColumnWithIdentifier:_lastSorted]];
            [_lastSorted release];
        }
        _lastSorted=[ident retain];
    }
    
    if (_ascending)
        [tableView setIndicatorImage:[NSImage imageNamed:@"NSAscendingSortIndicator"] 
                       inTableColumn:tableColumn];
    else 
        [tableView setIndicatorImage:[NSImage imageNamed:@"NSDescendingSortIndicator"] 
                       inTableColumn:tableColumn];
    
	//speedy sort (quick sort is faster than shaker sort, but not stable)
	[_networkData sortByColumn:_lastSorted order:_ascending];
	[tableView setHighlightedTableColumn:tableColumn];
    [self updateNetworkTable:self complete:YES];
}



#pragma mark -

- (BOOL)isSaved {
    if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"dontAskToSave"] boolValue]) return YES; //dont bother the user if set in preferences
    if ([_mainWindow isDocumentEdited]) return [_networksTable numberOfRows]==0; //dont ask to save empty documents
    return YES;
}

#pragma mark -
- (void)showAboutWindow:(id)sender 
{
    [_aboutWindow orderFront:_aboutWindow];
    [_aboutWindow center];
}

#pragma mark Application Delegates


- (void)showWantToSaveDialog:(SEL)overrideFunction {
    //[self menuSetEnabled:NO menu:[NSApp mainMenu]];
    NSBeginAlertSheet(
                      NSLocalizedString(@"Save Changes?", "Save changes dialog title"),
                      NSLocalizedString(@"Save", "Save changes dialog button"),
                      NSLocalizedString(@"Don't Save", "Save changes dialog button"),
                      CANCEL, _mainWindow, self, NULL, overrideFunction, self, 
                      NSLocalizedString(@"Save changes dialog text", "LONG dialog text")
                      //@"You have been scanning since your last save. Do you want to save your results?"
                      );
}

- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender 
{    
    if (![self isSaved]) {
		[self showWantToSaveDialog:@selector(reallyQuitDidEnd:returnCode:contextInfo:)];
        return NSTerminateLater;
    }
    
    return NSTerminateNow;
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    NSString* crashPath;
    NSFileManager *mang;
    NSUserDefaults *sets;
    
    //[self updatePrefs:nil];
    sets=[NSUserDefaults standardUserDefaults];
    
    crashPath = [@"~/Library/Logs/CrashReporter/KismetMAC.crash.log" stringByExpandingTildeInPath];
    mang = [NSFileManager defaultManager];
/*    
    if ([[sets objectForKey:@"SupressCrashReport"] intValue]!=1 && [mang fileExistsAtPath:crashPath] && [[[mang fileAttributesAtPath:crashPath traverseLink:NO] objectForKey:NSFileSize] intValue] != 0) {
        NSData *crashLog = [mang contentsAtPath:crashPath];
        CrashReportController* crc = [[CrashReportController alloc] initWithWindowNibName:@"CrashReporter"];
        [[crc window] setFrameUsingName:@"aKismetMAC_CRC"];
        [[crc window] setFrameAutosaveName:@"aKismetMAC_CRC"];
        
        [crc setReport:crashLog];
        [crc showWindow:self];
        [[crc window] makeKeyAndOrderFront:self];
        
        NSLog(@"crash occured the last time kismac started");
    }
    */
}

#pragma mark Main Window Delegates


- (BOOL)windowShouldClose:(id)sender {
    //NSUserDefaults *sets = [NSUserDefaults standardUserDefaults];
        

    [[NSTimer scheduledTimerWithTimeInterval:0.05 
                                      target:self 
                                    selector:@selector(fade:)
                                    userInfo:nil 
                                     repeats:YES] retain];
    return NO;
}


#pragma mark Fade Out Code

- (void)fade:(NSTimer *)timer {
    if ([_mainWindow alphaValue] > 0.0) {
        // If window is still partially opaque, reduce its opacity.
        [_mainWindow setAlphaValue:[_mainWindow alphaValue] - 0.2];
    } else {
        // Otherwise, if window is completely transparent, destroy the timer and close the window.
        [timer invalidate];
        [timer release];
        
        [_mainWindow close];
		[NSApp terminate:self];
    }
}

@end
